package base;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TableFrame extends JFrame {
    private JPanel center;
    private List<JCheckBox> tableCheckBoxes = new ArrayList<>();
    private JCheckBox selectAllCheckBox;
    private JCheckBox tableCheckBox;
    private JCheckBox viewCheckBox;
    private JTextField jTextField;
    private List<JCheckBox> viewCheckBoxes = new ArrayList<>();

    public TableFrame(String database) {
        setSize(580, 390);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setLayout(new BorderLayout());
        JPanel top = new JPanel();
        getContentPane().add(top, BorderLayout.NORTH);
        top.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
        top.setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
        tableCheckBox = new JCheckBox("表");
        tableCheckBox.setFocusPainted(false);
        tableCheckBox.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        tableCheckBox.setSelected(true);
        tableCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                selectAllCheckBox.setSelected(isAllSelected());
                showCheckBoxes();
            }
        });
        top.add(tableCheckBox);
        viewCheckBox = new JCheckBox("视图");
        viewCheckBox.setSelected(true);
        viewCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                selectAllCheckBox.setSelected(isAllSelected());
                showCheckBoxes();
            }
        });
        viewCheckBox.setFocusPainted(false);
        viewCheckBox.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        top.add(viewCheckBox);
        center = new JPanel();
        center.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
        JLabel label1 = new JLabel("请选择数据表：");
        label1.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        center.add(label1);
        this.selectAllCheckBox = new JCheckBox("全选");
        this.selectAllCheckBox.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        this.selectAllCheckBox.setFocusPainted(false);
        this.selectAllCheckBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                boolean b = TableFrame.this.selectAllCheckBox.isSelected();
                if(tableCheckBox.isSelected()){
                    for (JCheckBox checkBox1 : tableCheckBoxes) {
                        checkBox1.setSelected(b);
                    }
                }
                if(viewCheckBox.isSelected()){
                    for(JCheckBox jCheckBox : viewCheckBoxes){
                        jCheckBox.setSelected(b);
                    }
                }
            }
        });
        getContentPane().add(center, BorderLayout.CENTER);
        JPanel bottom = new JPanel();
        getContentPane().add(bottom, BorderLayout.SOUTH);
        bottom.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
        JLabel label = new JLabel("包路径");
        label.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        bottom.add(label);
        jTextField = new JTextField();
        jTextField.setPreferredSize(new Dimension(210, 27));
        bottom.add(jTextField);
        JButton jButton = new JButton("开始");
        jButton.setFont(new Font("微软雅黑", Font.PLAIN, 13));
        jButton.setFocusPainted(false);
        bottom.add(jButton);
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ArrayList<String> list = new ArrayList<>();
                if(tableCheckBox.isSelected()){
                    for (JCheckBox checkBox : tableCheckBoxes) {
                        if (checkBox.isSelected()) {
                            list.add(checkBox.getText());
                        }
                    }
                }
                if(viewCheckBox.isSelected()){
                    for (JCheckBox checkBox : viewCheckBoxes) {
                        if (checkBox.isSelected()) {
                            list.add(checkBox.getText());
                        }
                    }
                }
                if (list.size() == 0) {
                    return;
                }
                JFileChooser jFileChooser = new JFileChooser();
                jFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int i = jFileChooser.showSaveDialog(null);
                if (i == 1) {
                    return;
                }
                Statement statement = null;
                try {
                    statement = Connector.getConn().createStatement();
                    String sql = "use " + database;
                    statement.execute(sql);
                } catch (SQLException e1) {
                    JOptionPane.showMessageDialog(null, "执行出错，错误信息：\n" + e1.getMessage(), "提示", JOptionPane.WARNING_MESSAGE);
                    return;
                } finally {
                    if (statement != null) {
                        try {
                            statement.close();
                        } catch (SQLException e1) {
                        }
                    }
                }

                File selectedFile = jFileChooser.getSelectedFile();
                ArrayList<String> list1 = new ArrayList<>();
                for (String s : list) {
                    boolean b = createClass(s, selectedFile.toString());
                    if (!b) {
                        list1.add(s);
                    }
                }
                StringBuilder sb = new StringBuilder();
                sb.append("生成完毕!");
                int length = sb.length();
                for (String s : list1) {
                    if (sb.length() == length) {
                        sb.append("\n以下表生成失败：");
                    }
                    sb.append('\n');
                    sb.append(s);
                }
                JOptionPane.showMessageDialog(null, sb.toString(), "提示", JOptionPane.WARNING_MESSAGE);
            }
        });
        getViewCheckBoxes(database);
        getTableCheckBoxes(database);
        showCheckBoxes();
    }

    private boolean createClass(String table, String dir) {
        Connection conn = Connector.getConn();
        ResultSet resultSet = null;
        Statement statement = null;
        try {
            String sql = Utils.getFieldSql(table, Connector.getDbType());
            statement = conn.createStatement();
            resultSet = statement.executeQuery(sql);
            ResultSetMetaData metaData = resultSet.getMetaData();
            ArrayList<String> fields = new ArrayList<>();
            ArrayList<String> types = new ArrayList<>();
            for (int i = 1; i <= metaData.getColumnCount(); ++i) {
                String typeName = metaData.getColumnTypeName(i).toUpperCase();
                String type = Configuration.userTypeMapper.get(typeName);
                if (type == null) {
                    type = Configuration.standardTypeMapper.get(typeName);
                }
                if (type == null) {
                    type = metaData.getColumnClassName(i);
                    type = Utils.getArrayTypeBySymbol(type);
                }
                if (type != null) {
                    fields.add(metaData.getColumnName(i));
                    types.add(type);
                }
            }
            String aClass = Utils.createClass(table, jTextField.getText(), fields, types);
            boolean b = Utils.saveClass(aClass, dir + "\\" + Utils.getClassName(table) + ".java");
            if (!b) {
                return false;
            }

        } catch (Exception e) {
            return false;
        } finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                }
            }
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                }
            }
        }
        return true;
    }

    public void showCheckBoxes(){
        ArrayList<JCheckBox> jCheckBoxes = new ArrayList<>();
        if(tableCheckBox.isSelected()){
            jCheckBoxes.addAll(tableCheckBoxes);
        }
        if(viewCheckBox.isSelected()){
            jCheckBoxes.addAll(viewCheckBoxes);
        }
        Collections.sort(jCheckBoxes, new Comparator<JCheckBox>() {
            @Override
            public int compare(JCheckBox o1, JCheckBox o2) {
                return o1.getText().compareTo(o2.getText());
            }
        });
        center.removeAll();
        JLabel label1 = new JLabel("请选择表或视图(显示不全可放大窗口)：");
        label1.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        center.add(label1);
        center.add(selectAllCheckBox);
        Collections.sort(jCheckBoxes, new Comparator<JCheckBox>() {
            @Override
            public int compare(JCheckBox o1, JCheckBox o2) {
                return o1.getText().compareTo(o2.getText());
            }
        });
        for(JCheckBox checkBox : jCheckBoxes){
            center.add(checkBox);
        }
        repaint();
        revalidate();
    }

    private void getTableCheckBoxes(String database) {
        Connection conn = Connector.getConn();
        try {
            Statement statement = conn.createStatement();
            String sql = "use " + database;
            statement.execute(sql);
            sql = Configuration.getTableSqls[Connector.getDbType()];
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()) {
                String string = resultSet.getString(1);
                boolean b = false;
                for(JCheckBox checkBox : viewCheckBoxes){
                    if(checkBox.getText().equals(string)){
                        b = true;
                        break;
                    }
                }
                if(b){
                    continue;
                }
                JCheckBox jCheckBox = new JCheckBox(string);
                jCheckBox.setFocusPainted(false);
                jCheckBox.setFont(new Font("微软雅黑", Font.PLAIN, 14));
                jCheckBox.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (selectAllCheckBox.isSelected() && !jCheckBox.isSelected()) {
                            selectAllCheckBox.setSelected(false);
                        }
                        if (jCheckBox.isSelected()) {
                            selectAllCheckBox.setSelected(isAllSelected());
                        }
                    }
                });
                tableCheckBoxes.add(jCheckBox);
            }
            resultSet.close();
            revalidate();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "表获取失败，错误信息：\n" + e.getMessage(), "提示", JOptionPane.WARNING_MESSAGE);
        }
    }

    private void getViewCheckBoxes(String database) {
        Connection conn = Connector.getConn();
        try {
            Statement statement = conn.createStatement();
            String sql = "use " + database;
            statement.execute(sql);
            sql = Configuration.getViewSqls[Connector.getDbType()];
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()) {
                String string = resultSet.getString(1);
                JCheckBox jCheckBox = new JCheckBox(string);
                jCheckBox.setFocusPainted(false);
                jCheckBox.setFont(new Font("微软雅黑", Font.PLAIN, 14));
                jCheckBox.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (selectAllCheckBox.isSelected() && !jCheckBox.isSelected()) {
                            selectAllCheckBox.setSelected(false);
                        }
                        if (jCheckBox.isSelected()) {
                            selectAllCheckBox.setSelected(isAllSelected());
                        }
                    }
                });
                viewCheckBoxes.add(jCheckBox);
            }
            resultSet.close();
            revalidate();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "视图获取失败，错误信息：\n" + e.getMessage(), "提示", JOptionPane.WARNING_MESSAGE);
        }
    }

    public boolean isAllSelected(){
        if(tableCheckBox.isSelected()){
            for(JCheckBox checkBox : tableCheckBoxes){
                if(!checkBox.isSelected()){
                    return false;
                }
            }
        }
        if(viewCheckBox.isSelected()){
            for(JCheckBox checkBox : viewCheckBoxes){
                if(!checkBox.isSelected()){
                    return false;
                }
            }
        }
        return true;
    }
}
